package com.htg.util;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Stack;


public class UtilNavigation {

    //调起 腾讯地图路线规划 浏览器
    public static void guihuaTencentBrowser(Context context, double[] start, double[] end) {
        //
        start = UtilCoordinate.gps2AMapAndTencentMap(start[0],start[1]);
        end = UtilCoordinate.gps2AMapAndTencentMap(end[0],end[1]);
        //
        Uri uri = Uri.parse("https://apis.map.qq.com/uri/v1/routeplan?type=drive&from=起点&fromcoord=" + start[1] + "," + start[0] + "&to=终点&tocoord=" + end[1] + "," + end[0]+ "&policy=1&referer=4FZBZ-B46LU-SVWVN-42W2T-YNASV-5GB3K");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        context.startActivity(intent);
    }

    // 调起 腾讯地图路线规划 app
    public static void guihuaTencent(Context context, double[] start, double[] end) {
        //
        start = UtilCoordinate.gps2AMapAndTencentMap(start[0],start[1]);
        end = UtilCoordinate.gps2AMapAndTencentMap(end[0],end[1]);
        //
        Uri uri = Uri.parse("qqmap://map/routeplan?type=drive&fromcoord=" + start[1] + "," + start[0] + "&tocoord=" + end[1] + "," + end[0] + "&referer=4FZBZ-B46LU-SVWVN-42W2T-YNASV-5GB3K");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        context.startActivity(intent);
    }

    //调起 百度地图路线规划 浏览器
    public static void guihuaBaiduBrowser(Context context, double[] start, double[] end) {
        String uristr = "http://api.map.baidu.com/direction?origin=latlng:" + start[1] + "," + start[0] + "|name:起点&destination=latlng:" + end[1] + "," + end[0] + "|name:终点&coord_type=wgs84&mode=driving&src=andr.gcxh.cloud&output=html&region=中国";
        Uri uri = Uri.parse(uristr);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        context.startActivity(intent);
    }

    //调起 百度地图路线规划
    public static void guihuaBaidu(Context context, double[] start, double[] end) {
        Intent i1 = new Intent();

        // 公交路线规划
        double startlon = start[0];
        double startlat = start[1];
        double endlon = end[0];
        double endlat = end[1];
        i1.setData(Uri.parse("baidumap://map/direction?origin=name:|latlng:" + startlat + "," + startlon + "&destination=name:|latlng:" + endlat + "," + endlon + "&coord_type=wgs84&mode=driving&sy=3&index=0&target=1&src=andr.gcxh.cloud"));
        //i1.setData(Uri.parse("baidumap://map/direction?origin=name:对外经贸大学|latlng:39.98871,116.43234&destination=西直门&coord_type=bd09ll&mode=transit&sy=3&index=0&target=1&src=andr.gcxh.jilin"));
        context.startActivity(i1);
    }

    //调起 高德地图路线规划
    public static void guihuaAli(Context context, double[] start, double[] end) {
        //
        start = UtilCoordinate.gps2AMapAndTencentMap(start[0],start[1]);
        end = UtilCoordinate.gps2AMapAndTencentMap(end[0],end[1]);
        //
        String uri = String.format("amapuri://route/plan/?dlat=%s&dlon=%s&dname=B&dev=0&t=0&slat=" + start[1] + "&slon=" + start[0],
                end[1], end[0]);
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setData(Uri.parse(uri));
        intent.setPackage("com.autonavi.minimap");
        context.startActivity(intent);
    }

    //调起 高德地图 浏览器
    public static void guihuaAliBrowser(Context context, double[] start, double[] end) {
        //
        start = UtilCoordinate.gps2AMapAndTencentMap(start[0],start[1]);
        end = UtilCoordinate.gps2AMapAndTencentMap(end[0],end[1]);
        //
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.setData(Uri.parse("http://uri.amap.com/navigation?" +
                "from=" + start[0] + "," + start[1] +
                "&to=" + end[0] + "," + end[1] +
                "&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0"));
        context.startActivity(intent);
    }


    /**
     * 参数点集的第一个点为起点
     * 参数点集的最后一个点为终点
     * 其他为途经点
     * 从起点出发，先寻找距离最近的点，找到后再在剩余点中寻找与当前点最近的点，依次类推，给点集排序
     *
     * @param points
     * @return
     */
    public static List<double[]> navitOneByOneNear(List<double[]> points) {


        List<double[]> result = new ArrayList<>();
        result.add(points.get(0));
        result.add(points.get(points.size() - 1));

        int size = points.size();

        int forTimes = size - 2;

        double[] base = null;
        Iterator<double[]> iterator = null;
        for (int i = 0; i < forTimes; i++) {
            //初始化基点
            if (i == 0) {
                base = points.get(0);
            }

            //初始化目标点集
            if (i == 0) {
                points.remove(0);
                points.remove(points.size() - 1);

                iterator = points.iterator();
            } else {
                points.remove(base);
                iterator = points.iterator();
            }


            //在目标点集中 寻找距离基点最近的点
            double temp = Double.MAX_VALUE;
            double[] tempG = null;
            while (iterator.hasNext()) {
                double[] t = iterator.next();
                double dis = UtilTopology.distanceTwoPoint(base[0], base[1], t[0], t[1]);
                if (dis < temp) {
                    temp = dis;
                    tempG = t;
                }
            }
            result.add(result.size() - 1, tempG);
            base = tempG;

        }

        return result;

    }


    /**
     * 全程最短路径 规划算法
     *  对点集做所有可能的排序，然后计算相邻点距离和，取距离和最小的排序
     * @param points
     * @return
     */

    private static double[] start, end;
    private static List<double[]> mostNearOrderedPoints;
    public static List<double[]> navitMostNear(List<double[]> points) {

        start = points.get(0);
        end = points.get(points.size() - 1);

        points.remove(0);
        points.remove(points.size() - 1);


        Set<double[]> set = new HashSet<>();
        for (int i = 0; i < points.size(); i++) {
            double[] one = points.get(i);
            set.add(one);
        }

        tempDis = Double.MAX_VALUE;

        permutations(set, new Stack<double[]>(), set.size());

        double[][] copyArray = Arrays.copyOf(mostNearOrderedPoints.toArray(new double[][]{}),mostNearOrderedPoints.size());
        List<double[]> copyList = new ArrayList<>();
        for (int i=0;i<copyArray.length;i++){
            copyList.add(copyArray[i]);
        }


        return copyList;
    }


    /**
     * 对给定的一个集合 做出所有可能的排列
     *
     * @param items
     * @param permutation
     * @param size
     */
    private static double tempDis;
    private static void
    permutations(Set<double[]> items, Stack<double[]> permutation, int size) {

        /* permutation stack has become equal to size that we require */
        if (permutation.size() == size) {
            /* print the permutation */
            double dis = calculateWholeRouteLength(permutation);
            if (dis<tempDis){
                tempDis = dis;
                initMostNearOrderedPoints(permutation);
            }else{

            }
        }

        /* items available for permutation */
        double[][] availableItems = items.toArray(new double[][]{});
        for (double[] i : availableItems) {
            /* add current item */
            permutation.push(i);

            /* remove item from available item set */
            items.remove(i);

            /* pass it on for next permutation */
            permutations(items, permutation, size);

            /* pop and put the removed item back */
            items.add(permutation.pop());
        }
    }

    /**
     * 计算有序点集 相邻两点直线距离 总和
     * @param geoPointStack
     * @return
     */
    private static double calculateWholeRouteLength(Stack<double[]> geoPointStack){
        double[][] geoPoints = geoPointStack.toArray(new double[][]{});
        double allDis = 0;
        for ( int i=0;i<geoPoints.length-1;i++){
            double[] a = geoPoints[i];
            double[] b = geoPoints[i+1];
            double dis = UtilTopology.distanceTwoPoint(a[0],a[1],b[0],b[1]);
            allDis+=dis;
        }
        double startDis = UtilTopology.distanceTwoPoint(start[0],start[1],geoPoints[0][0],geoPoints[0][1]);
        allDis+=startDis;
        double endDis = UtilTopology.distanceTwoPoint(end[0],end[1],geoPoints[geoPoints.length-1][0],geoPoints[geoPoints.length-1][1]);
        allDis+=endDis;
        return allDis;
    }

    private static void initMostNearOrderedPoints(Stack<double[]> permutation){
        double[][] geoPoints = permutation.toArray(new double[][]{});
        if (mostNearOrderedPoints==null)
            mostNearOrderedPoints = new ArrayList<>();
        mostNearOrderedPoints.clear();
        mostNearOrderedPoints.add(start);
        for (int i=0;i<geoPoints.length;i++){
            mostNearOrderedPoints.add(geoPoints[i]);
        }
        mostNearOrderedPoints.add(end);

    }


}
